package com.signway.swmediaplayerdemo;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.signway.SignwayManager;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.View;

import androidx.annotation.NonNull;

import com.mstar.android.media.MMediaPlayer;
import com.signway.swmediaplayerdemo.databinding.ActivityImageBinding;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;

@SuppressLint("SdCardPath")
public class ImageActivity extends BaseActivity {
    private ActivityImageBinding binding;
    public static final String TAG = ImageActivity.class.getName();

    private SignwayManager sm;
    private long startMs = 0;
    private MMediaPlayer mImagePlayer = new MMediaPlayer();

    private int shotImageListIndex = 0;
    private ArrayList<String> shotImageList = new ArrayList<>();

    private int imagePathListIndex = 0;
    private String[] imagePathList = {
            "/sdcard/1920x1080_2.png",
            "/sdcard/1920x1080_3.png",
            "/sdcard/1920x1080_4.png",
            "/sdcard/1920x1080_5.png",
    };

    private static final int CMD_INIT = 0;
    private static final int CMD_START = 1;
    private static final int CMD_SHOT = 2;
    private static final int CMD_NEXT = 3;
    private static final int CMD_SHOW_IMAGE = 4;

    private HandlerThread handlerThread = null;
    private MediaPlayerHandler mHandler = null;

    private int shotIndex = 0;

    public class MediaPlayerHandler extends Handler {
        MediaPlayerHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(@NonNull Message msg) {
            Log.d(TAG, "handleMessage: " + msg.what);
            switch (msg.what) {
                case CMD_INIT: {
                    initPlayerImage();
                    mHandler.sendEmptyMessage(CMD_NEXT);
                } break;
                case CMD_START: {
                    mImagePlayer.start();
                } break;
                case CMD_SHOT: {
                    /* judge whether capture mode to use: vendor.mstar.screencap.mode
                     * 0: capture osd + video (default);
                     * 1: only video;
                     * 2: only osd.
                     */
                    Log.d(TAG, "shot screen start " + (SystemClock.elapsedRealtime() - startMs));
                    // 1. 截图
                    Bitmap bitmap = sm.shotScreen(0, 1);
                    // 2. 依据surfaceView进行裁剪
                    Log.d(TAG, "shot screen crop start " + (SystemClock.elapsedRealtime() - startMs));
                    int[] location = new int[2];
                    binding.surfaceViewImage.getLocationOnScreen(location);
                    int x = location[0]; // view距离 屏幕左边的距离（即x轴方向）
                    int y = location[1]; // view距离 屏幕顶边的距离（即y轴方向）
                    int width = binding.surfaceViewImage.getWidth();
                    int height = binding.surfaceViewImage.getHeight();
                    saveBitmap(bitmap, "/sdcard/screencapture/" + shotIndex + "_bck.jpg");
                    bitmap = Bitmap.createBitmap(bitmap, x, y, width, height);
                    Log.d(TAG, "createBitmap " + x + ", " + y + ", " + width + ", " + height);
                    Log.d(TAG, "shot screen save start " + (SystemClock.elapsedRealtime() - startMs));
                    // 3. 保存图片
                    String path = "/sdcard/screencapture/" + shotIndex + ".jpg";
                    saveBitmap(bitmap, path);
                    shotImageList.add(path);
                    shotIndex++;
                    Log.d(TAG, "shot screen end " + (SystemClock.elapsedRealtime() - startMs));
                    if (imagePathListIndex == imagePathList.length) {
                        Log.d(TAG, "截图完成.");
                        mImagePlayer.release();
                        runOnUiThread(() -> {
                            binding.surfaceViewImage.setVisibility(View.GONE);
                            binding.imageViewBack.setVisibility(View.GONE);
                            binding.imageView.setVisibility(View.VISIBLE);
                        });
                        mHandler.sendEmptyMessage(CMD_SHOW_IMAGE);
                    } else {
                        mHandler.sendEmptyMessage(CMD_NEXT);
                    }
                } break;
                case CMD_NEXT: {
                    startMs = SystemClock.elapsedRealtime();
                    mImagePlayer.reset();
                    String playerPath;
                    String imagePath = getNextImage();
                    Log.d(TAG, "imagePath " + imagePath);
                    if (getSystemRotate() == 0) {
                        playerPath = imagePath;
                    } else {/* 系统方法非0度时，需要旋转图片在进行播放 */
                        Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
                        Matrix matrix = new Matrix();
                        matrix.preRotate(getSystemRotate());
                        Bitmap bitmapRotate = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, false);
                        saveBitmap(bitmapRotate, "/sdcard/1.jpg");
                        playerPath = "/sdcard/1.jpg";
                        Log.d(TAG, "rotation time " + (SystemClock.elapsedRealtime() - startMs));
                    }
                    try {
                        mImagePlayer.setDataSource(playerPath);
                        mImagePlayer.prepare();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                } break;
                case CMD_SHOW_IMAGE: {
                    runOnUiThread(() -> {
                        String path = getNextScreen();
                        Log.d(TAG, "getNextScreen " + path);
                        if (path == null) {
                            finish();
                        } else {
                            //取控件当前的布局参数
                            binding.imageView.setImageBitmap(BitmapFactory.decodeFile(path));
                            mHandler.sendEmptyMessageDelayed(CMD_SHOW_IMAGE, 5_000);
                        }
                    });
                } break;
            }
        }
    }

    private String getNextScreen() {
        if (shotImageListIndex >= shotImageList.size())
            return null;

        String path = shotImageList.get(shotImageListIndex);
        shotImageListIndex++;
        return path;
    }

    private String getNextImage() {
        String path = imagePathList[imagePathListIndex];
        imagePathListIndex++;
        return path;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding  = ActivityImageBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());
        sm = getSystemService(SignwayManager.class);

        File file = new File("/sdcard/screencapture");
        if (!file.exists()) {
            file.mkdir();
        }

        handlerThread = new HandlerThread("mediaplayer");
        handlerThread.start();
        mHandler = new MediaPlayerHandler(Looper.getMainLooper());
        binding.surfaceViewImage.getHolder().addCallback(new SurfaceCallBack(ImageActivity.this, mImagePlayer));
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mHandler.removeCallbacksAndMessages(null);
        handlerThread.quitSafely();
    }

    private int getSystemRotate() {
        String orientation = SystemProperties.get("ro.surface_flinger.primary_display_orientation");
        if (orientation.equals("ORIENTATION_90")) {
            return 90;
        }
        if (orientation.equals("ORIENTATION_180")) {
            return 180;
        }
        if (orientation.equals("ORIENTATION_270")) {
            return 270;
        }
        return 0;
    }

    /**
     * 保存指纹图片
     * @param bitmap
     */
    private void saveBitmap(Bitmap bitmap, String path) {
        try {
            File file = new File(path);
            FileOutputStream fos = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
            fos.flush();
            fos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void initPlayerImage() {
        mImagePlayer.reset();
        mImagePlayer.setOnInfoListener((mp, what, extra) -> {
            Log.i(TAG, "onInfo what:" + what  + " extra:" + extra);
            if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START) {
                /* 等待显示完全在进行截图 */
                mHandler.sendEmptyMessageDelayed(CMD_SHOT, 500);
                return true;
            }
            return false;
        });
        mImagePlayer.setOnVideoSizeChangedListener((mp, width, height) -> {
            int imgWidth = mp.getVideoWidth();
            int imgHeight = mp.getVideoHeight();
            Log.i(TAG, "Video Size Changed: (" + imgWidth + "," + imgHeight + ")");
            mImagePlayer.SetImageSampleSize(1, imgWidth, imgHeight, null);
        });
        mImagePlayer.setOnPreparedListener(mp -> {
            Log.i(TAG, "setOnPreparedListener.");
            mHandler.sendEmptyMessage(CMD_START);
        });
    }

    private class SurfaceCallBack implements SurfaceHolder.Callback {
        public SurfaceCallBack(Context context, MediaPlayer player) {
        }

        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            Log.d(TAG, "surfaceCreated " + holder.toString());
            mImagePlayer.setDisplay(holder);
            mHandler.sendEmptyMessage(CMD_INIT);
        }

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
            Log.d(TAG, "surfaceChanged width " + width + ", height " + height);
        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            Log.d(TAG, "surfaceDestroyed");
        }
    }
}